package com.yanqu.road.server.manager.activity.suitang.manager;

import com.yanqu.road.entity.activity.suitang.config.*;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangData;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangUnionData;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangUnionJoinData;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangUserData;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefield;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefieldTeam;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangCity;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangCityEvent;
import com.yanqu.road.entity.activity.suitang.entity.city.CrossSuiTangCollect;
import com.yanqu.road.entity.activity.suitang.entity.group.CrossSuiTangGroup;
import com.yanqu.road.entity.activity.suitang.entity.team.CrossSuiTangTeam;
import com.yanqu.road.entity.activity.suitang.entity.team.CrossSuiTangTeamArrive;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionBuff;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionJoinMember;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionRound;
import com.yanqu.road.entity.activity.suitang.entity.user.CrossSuiTangUserRound;
import com.yanqu.road.entity.activity.suitang.enums.*;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.scene.UserSceneGroup;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.suitang.SuiTang;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

public class CrossSuiTangCityActivityMgr extends CrossBaseActivityMgr {
    /*
     * 管理如下数据
     * 城池数据 <union, <cityId, 城池数据>>
     * private Map<String, Map<Integer, CrossSuiTangCity>> cityMap;
     * 城池事件数据 <union, <cityId, 城池数据>>
     * private Map<String, Map<Integer, CrossSuiTangCityEvent>> cityEventMap;
     */
    protected static Logger logger = LogManager.getLogger(CrossSuiTangCityActivityMgr.class.getName());

    @Override
    public void init() {
        super.init();
        initCitySoldier();
    }

    /**
     * 城池事件刷新
     */
    public void crossSuiTangRefreshCityEventTask() {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null || config.getParamConfig() == null) {
            return;
        }
        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return;
        }
        if (crossSuiTangData.getStep().getValue() >= eSuiTangStage.Stage1EndTime.getValue()) {
            return;
        }
        List<Integer> suiTangEventRefreshTime = config.getParamConfig().getSuiTangEventRefreshTime();
        long refreshTime = getRefreshTime(suiTangEventRefreshTime, activity.getCrossSuiTangData().getRefreshTime());
        long now = System.currentTimeMillis();
        if (refreshTime > now || (calcRound() >= 3 && refreshTime == 0)) {
            return;
        }
        if (config.getSuiTangStage() != eSuiTangStage.ReadyTime && config.getSuiTangStage() != eSuiTangStage.Stage1Time) {
            return;
        }
        refreshCityEvent();
    }

    /*
     * refreshCityEvent
     */
    public void refreshCityEvent() {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null || config.getParamConfig() == null || config.getSuiTangStage().getValue() >= eSuiTangStage.Stage1EndTime.getValue()) {
            return;
        }
        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null || (calcRound() > 1 && crossSuiTangData.getRefreshTime() == 0)) {
            return;
        }
        List<Integer> suiTangEventRefreshTime = config.getParamConfig().getSuiTangEventRefreshTime();
        long refreshTime = getRefreshTime(suiTangEventRefreshTime, activity.getCrossSuiTangData().getRefreshTime());
        crossSuiTangData.setRefreshTime(refreshTime);

        initCityEvent();
        int suiTangEventCityType = config.getParamConfig().getSuiTangEventCityType();
        List<Integer> cityList = getCityListByType(suiTangEventCityType);
        Map<Integer, eSuiTangWarType> warTypeMapTemp = new ConcurrentHashMap<>();
        warTypeMapTemp.put(eSuiTangWarType.WAR_TYPE_YIJUN.getType(), eSuiTangWarType.WAR_TYPE_YIJUN);
        warTypeMapTemp.put(eSuiTangWarType.WAR_TYPE_XIAOQI.getType(), eSuiTangWarType.WAR_TYPE_XIAOQI);
        warTypeMapTemp.put(eSuiTangWarType.WAR_TYPE_JINJUN.getType(), eSuiTangWarType.WAR_TYPE_JINJUN);
        // 刷新所有战场和分组的buff
        for (int i = eSuiTangWarType.WAR_TYPE_YIJUN.getType(); i <= eSuiTangWarType.WAR_TYPE_JINJUN.getType(); i++) {
            Map<Integer, Map<Integer, CrossSuiTangCityEvent>> cityEventGroupMap = getCityEventGroupMap(warTypeMapTemp.get(i));
            if (cityEventGroupMap == null) {
                cityEventGroupMap = new ConcurrentHashMap<>();
            }
            Map<Integer, Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>>> actGroupMapTemp = activity.getCrossSuiTangData().getActGroupMap();
            if (actGroupMapTemp == null || actGroupMapTemp.isEmpty() || actGroupMapTemp.get(calcRound()) == null) {
                continue;
            }
            Map<Integer, CrossSuiTangGroup> actGroupMap = actGroupMapTemp.get(calcRound()).get(warTypeMapTemp.get(i));
            if (actGroupMap == null || actGroupMap.isEmpty()) {
                // 分组还没有出来
                continue;
            }
            for (Map.Entry<Integer, CrossSuiTangGroup> entry : actGroupMap.entrySet()) {
                Map<Integer, CrossSuiTangCityEvent> cityEventMap = cityEventGroupMap.get(entry.getKey());
                if (cityEventMap == null) {
                    cityEventMap = new ConcurrentHashMap<>();
                    cityEventGroupMap.put(entry.getKey(), cityEventMap);
                }
                List<Integer> suiTangEventCityBuffList = new ArrayList<>(config.getParamConfig().getSuiTangEventCityBuffList());
                if (suiTangEventCityBuffList.isEmpty()) {
                    //activity.addTask(new CrossSuiTangRefreshCityEventTask(activity, getRefreshTime(suiTangEventRefreshTime)));
                    return;
                }
                for (int cityId : cityList) {
                    // 随机 buff
                    int next = activity.getRandomHelper().next(0, suiTangEventCityBuffList.size());
                    int buffId = suiTangEventCityBuffList.get(next);
                    suiTangEventCityBuffList.remove(next);
                    CrossSuiTangCityEvent cityEvent = cityEventMap.getOrDefault(cityId, new CrossSuiTangCityEvent(config.getActivityId(), activity.getGroupId(),
                            entry.getKey(), calcRound(), warTypeMapTemp.get(i), cityId, buffId, refreshTime));
                    cityEvent.setBuffId(buffId);
                    cityEvent.setRefreshTime(refreshTime);
                    cityEvent.setRound(calcRound());
                    cityEvent.setActGroupId(entry.getKey());
                    cityEvent.setWarType(warTypeMapTemp.get(i));
                    cityEvent.setEndTime(getRefreshTime(suiTangEventRefreshTime, refreshTime));
                    cityEventMap.put(cityId, cityEvent);

                    // 处理下商会 buff
                    Map<Integer, CrossSuiTangCity> cityMap = getCityMap(warTypeMapTemp.get(i), entry.getKey());
                    if (cityMap == null) {
                        continue;
                    }
                    CrossSuiTangCity city = cityMap.get(cityId);
                    if (city != null && city.getUnionId() != null && !city.getUnionId().isEmpty()) {
                        List<CrossSuiTangUnionBuff> unionBuffs = getUnionData(city.getUnionId()).getUnionBuffMap();
                        CrossSuiTangUnionBuff unionBuff = null;
                        if (unionBuffs == null) {
                            unionBuffs = new ArrayList<>();
                        }
                        for (CrossSuiTangUnionBuff buff : unionBuffs) {
                            if (buff.getCityId() == cityId && config.getParamConfig().getSuiTangEventCityBuffList().contains(buff.getBuffId())) {
                                buff.setBuffId(buffId);
                                buff.setBeginTime(refreshTime);
                                buff.setEndTime(getRefreshTime(suiTangEventRefreshTime, refreshTime));
                                unionBuff = buff;
                                break;
                            }
                        }
                        if (unionBuff != null) {
                            getUnionData(city.getUnionId()).setUnionBuffMap(unionBuffs);
                            getUnionData(city.getUnionId()).setUpdateOption();
                            continue;
                        }
                        unionBuff = new CrossSuiTangUnionBuff(city.getUnionId(), refreshTime, getRefreshTime(suiTangEventRefreshTime, refreshTime), cityId, buffId);
                        unionBuffs.add(unionBuff);
                        getUnionData(city.getUnionId()).setUnionBuffMap(unionBuffs);
                        getUnionData(city.getUnionId()).setUpdateOption();
                        // buff 生效后处理
                        afterRefreshBuff(unionBuff, "");
                    }
                }
            }
        }
        //crossSuiTangData.setRefreshTime(refreshTime);
        activity.getSyncActivityMgr().syncCityEvent();
        logger.debug("【隋唐】城市事件刷新成功, 刷新时间：{}, 下次刷新时间：{}", DateHelper.getCurrentDateTimeString(refreshTime), DateHelper.getCurrentDateTimeString(getRefreshTime(suiTangEventRefreshTime, refreshTime)));
    }

    /*
     * initCityEvent
     */
    public void initCityEvent() {
        Map<Integer, Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCityEvent>>>> cityEventMap = activity.getCrossSuiTangData().getCityEventMap();
        if (cityEventMap == null) {
            cityEventMap = new ConcurrentHashMap<>();
            activity.getCrossSuiTangData().setCityEventMap(cityEventMap);
        }
        Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCityEvent>>> warTypeEnumMapMap = cityEventMap.get(calcRound());
        if (warTypeEnumMapMap == null) {
            warTypeEnumMapMap = new ConcurrentHashMap<>();
            cityEventMap.put(calcRound(), warTypeEnumMapMap);
        }
        if (warTypeEnumMapMap.isEmpty()) {
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_YIJUN, new ConcurrentHashMap<>());
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_XIAOQI, new ConcurrentHashMap<>());
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_JINJUN, new ConcurrentHashMap<>());
        }
    }

    /*
     * buff 刷新后处理
     */
    public void afterRefreshBuff(CrossSuiTangUnionBuff buff, String oldUnionId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        SuiTangBuffConfig buffConfig = config.getBuffConfigMap().get(buff.getBuffId());
        String unionId = buff.getUnionId();
        if (buffConfig.getType() == eSuiTangBuffType.Type7_ReadySoldierMaxNum.getValue()) {
            Map<Long, CrossSuiTangUserData> userDataMap = activity.getUserDataMap();
            if (userDataMap == null) {
                return;
            }
            for (CrossSuiTangUserData user : userDataMap.values()) {
                if (Objects.equals(user.getUnionUid(), unionId) || (!oldUnionId.isEmpty() && Objects.equals(user.getUnionUid(), oldUnionId))) {
                    activity.getBarracksActivityMgr().recalculateBarracksReadyMaxNum(user.getUserId());
                    activity.getSyncActivityMgr().syncBarracks(user.getUserId());
                }
            }
        }
    }

    /*
     * 获取刷新时间
     */
    public long getRefreshTime(List<Integer> suiTangEventRefreshTime, long oldRefreshTime) {
        if (calcRound() >= 3 && oldRefreshTime == 0) {
            // 最后一次刷过了，不要在刷了
            return 0;
        }

        long ret = 0;
        // 检查下刷新时间
        for (int hour : suiTangEventRefreshTime) {
            long refreshTime = DateHelper.getTodayZeroTimeStamp() + hour * DateHelper.HOUR_MILLIONS;
//            long oldRefreshTime = activity.getCrossSuiTangData().getRefreshTime();
            if (suiTangEventRefreshTime.get(suiTangEventRefreshTime.size() - 1) == hour && oldRefreshTime >= refreshTime) {
                // 明天再刷新
                ret = DateHelper.getTodayZeroTimeStamp() + 24 * DateHelper.HOUR_MILLIONS + suiTangEventRefreshTime.get(0) * DateHelper.HOUR_MILLIONS;
                if (calcRound() >= 3) {
                    // 第三轮结束，就不会再刷新了。
                    return 0;
                }
                return ret;
            }
            if (oldRefreshTime < refreshTime) {
                ret = refreshTime;
                break;
            }
        }
        return ret;
    }

    public List<Integer> getCityListByType(int type) {
        if (activity == null) {
            return null;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null || config.getParamConfig() == null) {
            return null;
        }
        List<Integer> list = new ArrayList<>();
        for (SuiTangCityConfig cityConfig : config.getCityConfigMap().values()) {
            if (cityConfig.getType() == type) {
                list.add(cityConfig.getId());
            }
        }
        return list;
    }

    public List<CrossSuiTangTeam> getCityTeam(long userId, Map<Integer, Long> cityTimeMap, long now) {
        List<CrossSuiTangTeam> ret = new ArrayList<>();

        Map<Integer, CrossSuiTangCity> curCityMap = getCurSceneCityMap(userId);
        if (curCityMap == null || curCityMap.isEmpty()) {
            return ret;
        }

        // 遍历城池中的队伍
        for (Map.Entry<Integer, Long> entry : cityTimeMap.entrySet()) {
            int cityId = entry.getKey();
            long time = entry.getValue();
            CrossSuiTangCity crossSuiTangCity = curCityMap.get(cityId);
            if (crossSuiTangCity == null) {
                continue;
            }
            for (CrossSuiTangTeam team : crossSuiTangCity.getMoveTeamList().values()) {
                CrossSuiTangUserData userData = activity.getUserData(team.getUserId());
                eSuiTangTeamStatus teamStatus = getTeamStatus(userData.getTeam());
                if (teamStatus == eSuiTangTeamStatus.Move && userData.getTeam().getMoveUpdateTime() >= time) {
                    ret.add(userData.getTeam());
                }
            }
        }
        return ret;
    }

    /*
     * 初始化城池的 npc 守军和一些数据
     */
    private void initCitySoldier() {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return;
        }

        Map<Integer, Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCity>>>> cityMap = crossSuiTangData.getCityMap();
        if (cityMap == null || cityMap.isEmpty()) {
            cityMap = new ConcurrentHashMap<>();
            cityMap.put(calcRound(), new ConcurrentHashMap<>());
        }
        Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCity>>> warTypeEnumMapMap = cityMap.get(calcRound());
        if (warTypeEnumMapMap == null) {
            warTypeEnumMapMap = new ConcurrentHashMap<>();
            cityMap.put(calcRound(), warTypeEnumMapMap);
        }
        if (warTypeEnumMapMap.isEmpty()) {
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_YIJUN, new ConcurrentHashMap<>());
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_XIAOQI, new ConcurrentHashMap<>());
            warTypeEnumMapMap.put(eSuiTangWarType.WAR_TYPE_JINJUN, new ConcurrentHashMap<>());
        }
        for (Map.Entry<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCity>>> entry : warTypeEnumMapMap.entrySet()) {
            Map<Integer, Map<Integer, CrossSuiTangCity>> actGroupMap = entry.getValue();
            eSuiTangWarType warType = entry.getKey();
            if (actGroupMap.isEmpty()) {
                Map<Integer, Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>>> actGroupSuiTang = activity.getCrossSuiTangData().getActGroupMap();
                if (actGroupSuiTang == null || actGroupSuiTang.isEmpty() || actGroupSuiTang.get(calcRound()) == null) {
                    continue;
                }
                Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>> actGroupMapTemp = actGroupSuiTang.get(calcRound());
                if (actGroupMapTemp == null || actGroupMapTemp.isEmpty()
                        || actGroupMapTemp.get(warType) == null || actGroupMapTemp.get(warType).isEmpty()) {
                    continue;
                }
                for (Map.Entry<Integer, CrossSuiTangGroup> entryGroup : actGroupMapTemp.get(warType).entrySet()) {
                    Integer actGroupId = entryGroup.getKey();
                    Map<Integer, CrossSuiTangCity> cityMapTemp = new ConcurrentHashMap<>();
                    for (SuiTangCityConfig cityConfig : config.getCityConfigMap().values()) {
                        CrossSuiTangCity city = new CrossSuiTangCity();
                        city.setInsertOption();
                        CrossSuiTangBattlefield battle = new CrossSuiTangBattlefield();
                        city.setActivityId(config.getActivityId());
                        city.setGroupId(activity.getGroupId());
                        city.setWarType(warType);
                        city.setActGroupId(actGroupId);
                        city.setBattlefield(battle);
                        city.setCityId(cityConfig.getId());
                        city.setRound(calcRound());
                        city.setCollectionTime(activity.getConfig().getStage1TimeList().get(calcRound() - 1).get(0));
                        if (cityConfig.getType() == eSuiTangCityType.CITY_TYPE_HOME.getType()) {
                            CrossSuiTangUnionData unionData = getUnionDataByCity(city);
                            if (unionData != null) {
                                city.setUnionId(unionData.getUnionUid());
                                city.setCollectionTime(activity.getConfig().getStage1TimeList().get(calcRound() - 1).get(0));
                            }
                            // 根据地初始阻击人数1
                            city.setNeedDefensePeople(1);
                            city.setUpdateDefensePeopleTime(System.currentTimeMillis());
                        }
                        initBattleField(city, true);
                        city.setMaxHp(city.getNpcGuardList().size());
                        cityMapTemp.put(cityConfig.getId(), city);
                    }
                    actGroupMap.put(actGroupId, cityMapTemp);
                }
            } else {
                for (Map<Integer, CrossSuiTangCity> cityGroupMap : actGroupMap.values()) {
                    if (cityGroupMap == null || cityGroupMap.isEmpty()) {
                        continue;
                    }
                    for (CrossSuiTangCity city : cityGroupMap.values()) {
                        if (city == null) {
                            continue;
                        }
                        initBattleField(city, false);
                    }
                }
            }
        }
        crossSuiTangData.setCityMap(cityMap);
        logger.debug("【隋唐】城市初始化完成");
    }

    /*
     * 初始城市的战斗区域
     */
    public void initBattleField(CrossSuiTangCity city, boolean isInit) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        Map<Integer, SuiTangCityTypeConfig> cityTypeConfigMap = config.getCityTypeConfigMap();
        Map<Integer, SuiTangCityConfig> cityConfigMap = config.getCityConfigMap();
        if (cityTypeConfigMap == null || cityTypeConfigMap.isEmpty()
                || cityConfigMap == null || cityConfigMap.isEmpty()
        ) {
            return;
        }
        SuiTangCityTypeConfig suiTangCityTypeConfig = cityTypeConfigMap.get(config.getCityTypeConfigKey(city.getWarType(), cityConfigMap.get(city.getCityId()).getType()));
        if (suiTangCityTypeConfig == null) {
            return;
        }

        CrossSuiTangBattlefield battlefield = city.getBattlefield();
        if (battlefield == null) {
            battlefield = new CrossSuiTangBattlefield();
            city.setBattlefield(battlefield);
        }
        long now = System.currentTimeMillis();
        battlefield.setCreateTime(now);
        if (isInit) {
            // 将军
            for (int i = 0; i < suiTangCityTypeConfig.getGeneralTeamNum(calcRound()); i++) {
                battlefield.getDefTeamMap().put((long) i, new CrossSuiTangBattlefieldTeam(i, suiTangCityTypeConfig.getGeneralSoldierNum(calcRound()), 2));
                city.getNpcGuardList().add((long) i);
            }
            // 士兵
            int sum = suiTangCityTypeConfig.getGeneralTeamNum(calcRound()) + suiTangCityTypeConfig.getTeamNum(calcRound());
            for (int i = suiTangCityTypeConfig.getGeneralTeamNum(calcRound()); i < sum; i++) {
                battlefield.getDefTeamMap().put((long) i, new CrossSuiTangBattlefieldTeam(i, suiTangCityTypeConfig.getSoldierNum(calcRound()), 1));
                city.getNpcGuardList().add((long) i);
            }
        } else {
            for (Long npcId : city.getNpcGuardList()) {
                if (npcId < suiTangCityTypeConfig.getGeneralTeamNum(calcRound())) {
                    // 将军
                    battlefield.getDefTeamMap().put(npcId, new CrossSuiTangBattlefieldTeam(npcId, suiTangCityTypeConfig.getGeneralSoldierNum(calcRound()), 2));
                } else {
                    // 士兵
                    battlefield.getDefTeamMap().put(npcId, new CrossSuiTangBattlefieldTeam(npcId, suiTangCityTypeConfig.getSoldierNum(calcRound()), 1));
                }
            }
        }

        // 玩家
        // 为了兼容热更，增加了一段无用代码，后续可去掉
        List<CrossSuiTangUserData> collect = activity.getUserDataMap().values().stream().filter(item -> {
            CrossSuiTangCity cityUser = getCity(0);
            city.getCityId();
            return false;
        }).collect(Collectors.toList());
        List<CrossSuiTangUserData> userDataList = new ArrayList<>();
        for (CrossSuiTangUserData userData : activity.getUserDataMap().values()) {
            CrossSuiTangCity cityUser = getCity(userData.getUserId());
            CrossSuiTangUserRound curUserRound = getCurUserRound(userData.getUserId());
            if (isInit) {
                if (curUserRound != null && curUserRound.getCityId() == city.getCityId()
                        && curUserRound.getWarType().getType() == city.getWarType().getType()
                        && curUserRound.getActGroupId() == city.getActGroupId()) {
                    userDataList.add(userData);
                }
            } else {
                if (cityUser != null && cityUser.getCityId() == city.getCityId()
                        && cityUser.getWarType().getType() == city.getWarType().getType()
                        && cityUser.getActGroupId() == city.getActGroupId()) {
                    userDataList.add(userData);
                }
            }
        }
        for (CrossSuiTangUserData userData : userDataList) {
            CrossSuiTangTeam team = userData.getTeam();
            if (team != null && team.getSoldierNum() > 0) {
                if (team.getCityId() != city.getCityId()) {
                    continue;
                }
                if (userData.getUnionUid().equals(city.getUnionId())) {
                    battlefield.getDefTeamMap().put(userData.getUserId(), new CrossSuiTangBattlefieldTeam(new CrossSuiTangTeamArrive(userData.getUserId(), now)));
                } else {
                    battlefield.getAtkTeamMap().put(userData.getUserId(), new CrossSuiTangBattlefieldTeam(new CrossSuiTangTeamArrive(userData.getUserId(), now)));
                }
            }
        }
        city.setUpdateOption();
    }

    public void addCityDefTeamMap(long userId, CrossSuiTangCity city) {
        if (city == null) {
            return;
        }
        synchronized (getCityLock(city)) {
            CrossSuiTangBattlefield battlefield = city.getBattlefield();
            if (battlefield == null) {
                return;
            }
            CrossSuiTangTeam team = getTeam(userId);
            if (team != null && team.getSoldierNum() > 0 && !battlefield.getDefTeamMap().containsKey(userId) && city.getUnionId().equals(activity.getUserData(userId).getUnionUid())) {
                if (!isOut(userId)) {
                    battlefield.getDefTeamMap().put(userId, new CrossSuiTangBattlefieldTeam(new CrossSuiTangTeamArrive(userId, System.currentTimeMillis())));
                }
            }
        }
    }

    /*
     * 城池易主buff处理
     */
    public void handleCityEventChangeUnion(CrossSuiTangCity city, String oldUnionId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        int suiTangEventCityType = config.getParamConfig().getSuiTangEventCityType();
        List<Integer> cityList = getCityListByType(suiTangEventCityType);
        if (!cityList.contains(city.getCityId())) {
            return;
        }
        Map<Integer, CrossSuiTangCityEvent> cityEventMap = getCityEventMap(city.getWarType(), city.getActGroupId());
        if (cityEventMap == null || cityEventMap.isEmpty()) {
            return;
        }
        // 更改buff的归属
        CrossSuiTangCityEvent cityEvent = cityEventMap.get(city.getCityId());
        if (cityEvent == null) {
            return;
        }
        cityEvent.setUnionId(city.getUnionId());

        // 清除旧商会的buff
        CrossSuiTangUnionBuff unionBuff = null;
        if (!oldUnionId.isEmpty()) {
            List<CrossSuiTangUnionBuff> buffs = getUnionData(oldUnionId).getUnionBuffMap();
            if (buffs != null && !buffs.isEmpty()) {
                for (CrossSuiTangUnionBuff buff : buffs) {
                    if (buff.getBuffId() == cityEvent.getBuffId()) {
                        unionBuff = buff;
                        break;
                    }
                }
                if (unionBuff != null) {
                    buffs.remove(unionBuff);
                    getUnionData(oldUnionId).setUpdateOption();
                } else {
                    unionBuff = new CrossSuiTangUnionBuff(city.getUnionId(), cityEvent.getBeginWriteTime(), cityEvent.getEndTime(), cityEvent.getCityId(), cityEvent.getBuffId());
                }
            }
        } else {
            unionBuff = new CrossSuiTangUnionBuff(city.getUnionId(), cityEvent.getBeginWriteTime(), cityEvent.getEndTime(), cityEvent.getCityId(), cityEvent.getBuffId());
        }


        if (unionBuff == null) {
            return;
        }

        // 给新商会加 buff
        List<CrossSuiTangUnionBuff> buffCityUnion = getUnionData(city.getUnionId()).getUnionBuffMap();
        if (buffCityUnion == null) {
            buffCityUnion = new ArrayList<>();
        }
        unionBuff.setUnionId(cityEvent.getUnionId());
        buffCityUnion.add(unionBuff);
        getUnionData(city.getUnionId()).setUnionBuffMap(buffCityUnion);
        getUnionData(city.getUnionId()).setUpdateOption();

        // buff 生效后处理
        afterRefreshBuff(unionBuff, oldUnionId);
    }

    /*
     * 处理叠加buff
     */
    public void handleCityTypeBuffsChangeUnion(CrossSuiTangCity city, String oldUnionId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        SuiTangCityTypeConfig cityTypeConfig = getCityTypeConfig(city);
        if (cityTypeConfig.getType() != eSuiTangCityType.CITY_TYPE_GUANCHENG.getType()
                && cityTypeConfig.getType() != eSuiTangCityType.CITY_TYPE_ZHOUFU.getType()) {
            return;
        }

        // 清除旧商会的buff
        CrossSuiTangUnionBuff unionBuff = null;
        if (!oldUnionId.isEmpty()) {
            List<CrossSuiTangUnionBuff> buffs = getUnionData(oldUnionId).getUnionBuffMap();
            if (buffs != null && !buffs.isEmpty()) {
                for (CrossSuiTangUnionBuff buff : buffs) {
                    SuiTangBuffConfig buffConfig = activity.getConfig().getBuffConfigMap().get(buff.getBuffId());
                    if (buffConfig != null
                            && (buffConfig.getType() == eSuiTangBuffType.Type8_CityFoodProduce.getValue() || buffConfig.getType() == eSuiTangBuffType.Type7_ReadySoldierMaxNum.getValue())
                            && buff.getCityId() == city.getCityId()
                    ) {
                        unionBuff = buff;
                        break;
                    }
                }
                if (unionBuff != null) {
                    buffs.remove(unionBuff);
                    getUnionData(oldUnionId).setUpdateOption();
                } else {
                    int buffId = getBuffIdByType(cityTypeConfig.getType() == eSuiTangCityType.CITY_TYPE_GUANCHENG.getType() ? eSuiTangBuffType.Type7_ReadySoldierMaxNum : eSuiTangBuffType.Type8_CityFoodProduce);
                    if (buffId != 0) {
                        unionBuff = new CrossSuiTangUnionBuff(city.getUnionId(), System.currentTimeMillis(), city.getCityId(), buffId);
                    }
                }
            }
        } else {
            int buffId = getBuffIdByType(cityTypeConfig.getType() == eSuiTangCityType.CITY_TYPE_GUANCHENG.getType() ? eSuiTangBuffType.Type7_ReadySoldierMaxNum : eSuiTangBuffType.Type8_CityFoodProduce);
            if (buffId != 0) {
                unionBuff = new CrossSuiTangUnionBuff(city.getUnionId(), System.currentTimeMillis(), city.getCityId(), buffId);
            }
        }

        if (unionBuff == null) {
            return;
        }

        // 给新商会加 buff
        List<CrossSuiTangUnionBuff> buffCityUnion = getUnionData(city.getUnionId()).getUnionBuffMap();
        if (buffCityUnion == null) {
            buffCityUnion = new ArrayList<>();
        }
        unionBuff.setUnionId(city.getUnionId());
        buffCityUnion.add(unionBuff);
        getUnionData(city.getUnionId()).setUnionBuffMap(buffCityUnion);
        getUnionData(city.getUnionId()).setUpdateOption();

        // buff 生效后处理
        afterRefreshBuff(unionBuff, oldUnionId);
    }

    /*
     * 城池易主定时任务
     */
    public void crossCityChangeUnion(String newUnionId, String oldUnionId, CrossSuiTangCity city) {
        if (city == null) {
            return;
        }
        long now = System.currentTimeMillis();
        // 计算下城市的收益
        if (!oldUnionId.isEmpty()) {
            makeAllCityCollect(oldUnionId, now, calcRound());
        }
        // 城池被攻占，采集时间也要从占领这一刻开始计算
        city.setUnionId(newUnionId);
        city.setCollectionTime(now);
        // 重新初始化城市相关
        handleCityChangeUnion(city, oldUnionId);
        handleCityEventChangeUnion(city, oldUnionId);
        handleCityTypeBuffsChangeUnion(city, oldUnionId);
    }

    /*
     * 城池易主
     */
    public void handleCityChangeUnion(CrossSuiTangCity city, String oldUnionId) {
        if (activity == null) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        Map<Integer, SuiTangCityTypeConfig> cityTypeConfigMap = config.getCityTypeConfigMap();
        Map<Integer, SuiTangCityConfig> cityConfigMap = config.getCityConfigMap();
        if (cityTypeConfigMap == null || cityTypeConfigMap.isEmpty()
                || cityConfigMap == null || cityConfigMap.isEmpty()
        ) {
            return;
        }
        SuiTangCityTypeConfig suiTangCityTypeConfig = cityTypeConfigMap.get(config.getCityTypeConfigKey(city.getWarType(), cityConfigMap.get(city.getCityId()).getType()));
        if (suiTangCityTypeConfig == null) {
            return;
        }

        long now = System.currentTimeMillis();
        synchronized (getCityLock(city)) {
            CrossSuiTangBattlefield battlefield = city.getBattlefield();

            battlefield.setCreateTime(now);
            Map<Long, CrossSuiTangBattlefieldTeam> defTeamMap = battlefield.getDefTeamMap();
            // 防守队列中可能还有行军中的玩家，将其更改到进攻队列
            for (CrossSuiTangBattlefieldTeam team : defTeamMap.values()) {
                if (team.getTeam() != null) {
                    battlefield.getAtkTeamMap().put(team.getTeamNo(), team);
                }
            }
            defTeamMap.clear();
            // 将军
            for (int i = 0; i < suiTangCityTypeConfig.getGeneralTeamNum(calcRound()); i++) {
                defTeamMap.put((long) i, new CrossSuiTangBattlefieldTeam(i, suiTangCityTypeConfig.getGeneralSoldierNum(calcRound()), 2));
                city.getNpcGuardList().add((long) i);
            }
            // 士兵
            int sum = suiTangCityTypeConfig.getGeneralTeamNum(calcRound()) + suiTangCityTypeConfig.getTeamNum(calcRound());
            for (int i = suiTangCityTypeConfig.getGeneralTeamNum(calcRound()); i < sum; i++) {
                defTeamMap.put((long) i, new CrossSuiTangBattlefieldTeam(i, suiTangCityTypeConfig.getSoldierNum(calcRound()), 1));
                city.getNpcGuardList().add((long) i);
            }
            // 进攻队列中本商会的玩家加入防守队列
            List<Long> removeList = new ArrayList<>();
            for (CrossSuiTangBattlefieldTeam team : battlefield.getAtkTeamMap().values()) {
                if (Objects.equals(activity.getUserData(team.getTeamNo()).getUnionUid(), city.getUnionId())) {
                    defTeamMap.put(team.getTeamNo(), team);
                    removeList.add(team.getTeamNo());
                }
            }
            for (long teamId : removeList) {
                battlefield.getAtkTeamMap().remove(teamId);
            }
        }

        // 检查下是否开启阴山
        int yinShanCityId = 6001;
        if (canOpenYinShanCity(city) && city.getCityId() != yinShanCityId) {
            // 同步阴山开启
            CrossSuiTangCity cityYinShan = getCity(city.getWarType(), city.getActGroupId(), yinShanCityId);
            activity.getSyncActivityMgr().syncCity(cityYinShan, true);
            SuiTang.SuiTangSyncCenterCityRespMsg.Builder builder = SuiTang.SuiTangSyncCenterCityRespMsg.newBuilder();
            builder.setRound(calcRound());
            builder.setWarType(city.getWarType().getType());
            builder.setActGroupId(city.getActGroupId());
            activity.sendPacketToAll(ClientProtocol.U_SUI_TANG_SYNC_CENTER_CITY, builder, getUnionJoin(city.getUnionId()).getMemberMap().keySet());
        }

        // 更新势力积分
        int campPoint = suiTangCityTypeConfig.getCampPoint(calcRound() - 1);
        updateCampPoint(city.getUnionId(), campPoint);
        if (!oldUnionId.isEmpty()) {
            updateCampPoint(oldUnionId, -campPoint);
        }

        // 淘汰处理
        handleOut(oldUnionId, city);

        // 更新榜单
        CrossSuiTangUnionRound unionRoundData = getUnionRoundData(city.getUnionId());
        if (unionRoundData != null) {
            activity.getRankActivityMgr().updateWarUnionRank(city.getUnionId(), unionRoundData.getCurrentCityScore().longValue(), now);
        }
        if (!oldUnionId.isEmpty()) {
            CrossSuiTangUnionRound unionRoundDataOld = getUnionRoundData(oldUnionId);
            if (unionRoundDataOld != null) {
                activity.getRankActivityMgr().updateWarUnionRank(oldUnionId, unionRoundDataOld.getCurrentCityScore().longValue(), now);
            }
        }

        // 更新商会任务
        handleUnionTask(city);

        // 生成战报
        activity.getBattleActivityMgr().recordCityWarReport(city, false, city.getUnionId(), oldUnionId);

        if (oldUnionId.isEmpty() || !isHomeCity(city, oldUnionId)) {
            activity.getSyncActivityMgr().syncTopMsg(false, false, city.getUnionId(), oldUnionId, city);
        }
        synchronized (getCityLock(city)) {
            city.setStatus(0);
            city.setChangeStatusTime(now);
            city.setUpdateDefensePeopleTime(now);
        }
        // 同步城池数据
        activity.getSyncActivityMgr().syncCity(city, true);
        activity.getSyncActivityMgr().syncBattleResultMsg(city);
    }

    /*
     * 处理商会任务
     */
    public void handleUnionTask(CrossSuiTangCity city) {
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        Map<Integer, SuiTangCityTypeConfig> cityTypeConfigMap = config.getCityTypeConfigMap();
        Map<Integer, SuiTangCityConfig> cityConfigMap = config.getCityConfigMap();
        if (cityTypeConfigMap == null || cityTypeConfigMap.isEmpty()
                || cityConfigMap == null || cityConfigMap.isEmpty()
        ) {
            return;
        }
        SuiTangCityTypeConfig suiTangCityTypeConfig = cityTypeConfigMap.get(config.getCityTypeConfigKey(city.getWarType(), cityConfigMap.get(city.getCityId()).getType()));
        if (suiTangCityTypeConfig == null) {
            return;
        }

        eGamePlayerEventType type = null;
        if (suiTangCityTypeConfig.getType() == eSuiTangCityType.CITY_TYPE_ZHOUFU.getType()) {
            type = eGamePlayerEventType.SuiTangUnionZhanLingZC;
        }
        if (suiTangCityTypeConfig.getType() == eSuiTangCityType.CITY_TYPE_GUANCHENG.getType()) {
            type = eGamePlayerEventType.SuiTangUnionZhanLingGC;
        }
        if (suiTangCityTypeConfig.getType() == eSuiTangCityType.CITY_TYPE_XIANCHENG.getType()) {
            type = eGamePlayerEventType.SuiTangUnionZhanLingXC;
        }
        if (type != null) {
            CrossSuiTangUnionRound unionRoundData = getUnionRoundData(city.getUnionId());
            if (unionRoundData == null) {
                return;
            }
            unionRoundData.getUnionTaskMap().put(type.getValue(), unionRoundData.getUnionTaskMap().getOrDefault(type.getValue(), 0) + 1);
            getUnionData(unionRoundData.getUnionUid()).setUpdateOption();
            activity.getSyncActivityMgr().notifyConditionChangeToUnion(city.getUnionId(), type, getUnionRoundData(city.getUnionId()).getUnionTaskMap().get(type.getValue()), "1");
        }
    }

    /*
     * 处理淘汰
     */
    public void handleOut(String oldUnionId, CrossSuiTangCity city) {
        if (oldUnionId.isEmpty()|| !isHomeCity(city, oldUnionId)) {
            return;
        }

        // 旧商会的的根据地被占领，需要处理相关商会所有城市数据
        CrossSuiTangUnionRound unionRoundData = getUnionRoundData(oldUnionId);
        unionRoundData.setOut(true);
        unionRoundData.setOutTime(System.currentTimeMillis());
        unionRoundData.setCurrentCityScore(new AtomicLong(0));
        Map<Integer, CrossSuiTangCity> cityMap = getCityMap(unionRoundData.getWarType(), unionRoundData.getActGroupId());
        for (CrossSuiTangCity cityTemp : cityMap.values()) {
            synchronized (getCityLock(cityTemp)) {
                if (Objects.equals(cityTemp.getUnionId(), oldUnionId)) {
                    cityTemp.setUnionId("");
                    List<Long> removeList = new ArrayList<>();
                    for (CrossSuiTangBattlefieldTeam team : cityTemp.getBattlefield().getDefTeamMap().values()) {
                        if (team.getTeam() != null && activity.getUserData(team.getTeamNo()) != null && activity.getUserData(team.getTeamNo()).getUnionUid().equals(oldUnionId)){
                            removeList.add(team.getTeamNo());
                        }
                    }
                    for (Long userId : removeList) {
                        cityTemp.getBattlefield().getDefTeamMap().remove(userId);
                    }
                    removeList.clear();
                    for (CrossSuiTangBattlefieldTeam team : cityTemp.getBattlefield().getAtkTeamMap().values()) {
                        if (activity.getUserData(team.getTeamNo()) != null && activity.getUserData(team.getTeamNo()).getUnionUid().equals(oldUnionId)){
                            removeList.add(team.getTeamNo());
                        }
                    }
                    for (Long userId : removeList) {
                        cityTemp.getBattlefield().getAtkTeamMap().remove(userId);
                    }
                    activity.getSyncActivityMgr().syncCity(cityTemp, true);
                    activity.getSyncActivityMgr().syncBattleResultMsg(cityTemp);
                }
            }
        }

        // 同步一下淘汰的跑马灯
        activity.getSyncActivityMgr().syncTopMsg(false, true, city.getUnionId(), oldUnionId, city);
    }

    /*
     * 更新势力点
     */
    public void updateCampPoint(String unionId, int campPoint) {
        CrossSuiTangUnionRound unionRoundData = getUnionRoundData(unionId);
        if (unionRoundData != null) {
            unionRoundData.setCurrentCityScore(new AtomicLong(Math.max(unionRoundData.getCurrentCityScore().addAndGet(campPoint), 0)));
        }
    }

    /*
     * 恢复守军
     */
    public void recoverCitySolder(CrossSuiTangCity city) {
        if (city == null || activity == null || activity.getConfig() == null) {
            return;
        }

        synchronized (getCityLock(city)) {
            if (city.getStatus() == 1) {
                return;
            }

            CrossSuiTangBattlefield battlefield = city.getBattlefield();
            if (battlefield == null) {
                return;
            }
            SuiTangCityTypeConfig cityTypeConfig = getCityTypeConfig(city);
            SuiTangParamConfig config = activity.getConfig().getParamConfig();
            if (cityTypeConfig == null || config == null) {
                return;
            }
            int npcSum = cityTypeConfig.getTeamNum(calcRound()) + cityTypeConfig.getGeneralTeamNum(calcRound());
            if (city.getNpcGuardList().size() >= npcSum) {
                return;
            }
            long now = System.currentTimeMillis();
            boolean isFirst = city.getTeamRecoveryBeginTime() == 0;
            long recoverTime = isFirst ? city.getLastRecoveryExtraTeamTime() + config.getSuiTangCitySoldierRecoverTimeFirst() * DateHelper.SECOND_MILLIONS : city.getLastRecoveryExtraTeamTime() + config.getSuiTangCitySoldierRecoverTime() * DateHelper.SECOND_MILLIONS;
            if (recoverTime >= now) {
                // 未到恢复时间
                // activity.addTask(new CrossSuiTangCityTeamRecoveryTask(activity, recoverTime, city));
                return;
            }

            logger.debug("【隋唐】城市守军恢复任务：{}", city.getCityId());

            // 先统计需要恢复的npc的id并排序，根据id从后往前恢复（小兵id比较大，在后面）
            List<Long> list = new ArrayList<>();
            for (long i = 0; i < npcSum; i++) {
                if (!city.getNpcGuardList().contains(i)) {
                    list.add(i);
                } else {
                    // 活着的恢复一下血量
                    CrossSuiTangBattlefieldTeam team = city.getBattlefield().getDefTeamMap().get(i);
                    if (team != null) {
                        int soldierNum = team.getSoldierType() == 1 ? cityTypeConfig.getSoldierNum(calcRound()) : cityTypeConfig.getGeneralSoldierNum(calcRound());
                        team.setSoldierNum(soldierNum);
                    }
                }
            }

            int recoverTeamNum = isFirst ? cityTypeConfig.getFirstRecoverTeamNum(calcRound()) : cityTypeConfig.getRecoverTeamNum(calcRound());
            for (int i = list.size() - 1; i >= 0 && recoverTeamNum > 0; i--) {
                if (city.getNpcGuardList().size() >= npcSum) {
                    break;
                }
                city.getNpcGuardList().add(list.get(i));
                if (list.get(i) >= cityTypeConfig.getGeneralTeamNum(calcRound())) {
                    // 小兵
                    battlefield.getDefTeamMap().put(list.get(i), new CrossSuiTangBattlefieldTeam(list.get(i), cityTypeConfig.getSoldierNum(calcRound()), 1));
                } else {
                    battlefield.getDefTeamMap().put(list.get(i), new CrossSuiTangBattlefieldTeam(list.get(i), cityTypeConfig.getGeneralSoldierNum(calcRound()), 2));
                }

                recoverTeamNum--;
            }
            city.setTeamRecoveryBeginTime(now);
            city.setLastRecoveryExtraTeamTime(now);
            activity.getCrossSuiTangData().setUpdateOption();
        }

        // 同步城池数据
        activity.getSyncActivityMgr().syncCity(city, false);
        activity.getSyncActivityMgr().syncBattleResultMsg(city);
    }

    public boolean canOpenYinShanCity(CrossSuiTangCity city) {
        // 检查下是否需要开启阴山
        boolean isOpen = true;
        int yinShanCityId = 6001;
        Map<Integer, CrossSuiTangCity> cityMap = getCityMap(city.getWarType(), city.getActGroupId());
        for (CrossSuiTangCity cityTemp : cityMap.values()) {
            if (!Objects.equals(cityTemp.getUnionId(), city.getUnionId()) && cityTemp.getCityId() != yinShanCityId) {
                isOpen = false;
                break;
            }
        }

        return isOpen;
    }

    public boolean canOpenYinShanCity(eSuiTangWarType warType, int actGroupId) {
        // 检查下是否需要开启阴山
        List<String> unionIdList = new ArrayList<>();
        int yinShanCityId = 6001;
        Map<Integer, CrossSuiTangCity> cityMap = getCityMap(warType, actGroupId);
        if (cityMap == null) {
            return false;
        }
        for (CrossSuiTangCity cityTemp : cityMap.values()) {
            if (!unionIdList.contains(cityTemp.getUnionId()) && cityTemp.getCityId() != yinShanCityId) {
                unionIdList.add(cityTemp.getUnionId());
            }
        }

        return unionIdList.size() == 1;
    }

    public boolean canOpenCenterCity() {
        // 检查下是否需要开启中心城
        if (System.currentTimeMillis() < activity.getConfig().getActivityInfo().getBeginTime() + (activity.getConfig().getParamConfig().getSuiTangSecondStageTime().get(calcRound() - 1).get(0) - 1) * DateHelper.DAY_MILLIONS
                + activity.getConfig().getParamConfig().getSuiTangSecondStageTime().get(calcRound() - 1).get(1) * DateHelper.HOUR_MILLIONS) {
            return false;
        }

        return true;
    }

    public boolean inProtectTime(CrossSuiTangCity city) {
        SuiTangCityTypeConfig cityTypeConfig = getCityTypeConfig(city);
        if (cityTypeConfig == null) {
            return false;
        }
        List<Integer> list = StringUtils.stringToIntegerList(cityTypeConfig.getProtectTime(), ";");
        if (list == null || list.isEmpty() || list.size() < 2) {
            return false;
        }
        long now = System.currentTimeMillis();
        if (now >= DateHelper.getTodayZeroTimeStamp() + list.get(0) * DateHelper.HOUR_MILLIONS
                && now < DateHelper.getTodayZeroTimeStamp() + list.get(1) * DateHelper.HOUR_MILLIONS) {
            return true;
        }
        return false;
    }

    /**
     * 触发城池的采集收益 只触发对应阵营的
     * 玩家点击要领取的时候触发下，被打下来触发下，buff失效的时候触发下
     */
    public void makeAllCityCollect(String unionId, long dealTime, int round) {
        // 阵营空、未生成数据，不处理
        if (unionId.isEmpty() || activity == null) {
            return;
        }
        Map<String, CrossSuiTangUnionData> unionDataMap = activity.getUnionDataMap();
        if (unionDataMap == null || !unionDataMap.containsKey(unionId)) {
            return;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return;
        }
        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return;
        }

        List<Integer> needDealCity = new ArrayList<>();
        long nowTime = dealTime;
        Map<Integer, SuiTangCityConfig> cityConfigMap = config.getCityConfigMap();
        Map<Integer, Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCity>>>> cityMap = crossSuiTangData.getCityMap();
        CrossSuiTangUnionData unionData = unionDataMap.get(unionId);
        if (unionData == null || unionData.getUnionRoundMap() == null || unionData.getUnionRoundMap().isEmpty()) {
            return;
        }
        CrossSuiTangUnionRound unionRound = unionData.getUnionRoundMap().get(round);
        if (unionRound == null) {
            return;
        }

        synchronized (activity.getLock()) {
            // 获取有收益的城池
            for (CrossSuiTangCity city : cityMap.get(unionRound.getRound()).get(unionRound.getWarType()).get(unionRound.getActGroupId()).values()) {
                if (!Objects.equals(city.getUnionId(), unionId)) {
                    continue;
                }
                SuiTangCityConfig cityConfig = cityConfigMap.get(city.getCityId());
                SuiTangCityTypeConfig cityTypeConfig = config.getCityTypeConfigMap().get(config.getCityTypeConfigKey(city.getWarType(), cityConfig.getType()));
                // 每分钟产生一次收益
                if (cityTypeConfig.getFoodProduction() > 0 && nowTime - city.getCollectionTime() >= DateHelper.MINUTE_MILLIONS) {
                    needDealCity.add(city.getCityId());
                }
            }
            // 城池加采集奖励
            Map<Long, Map<Integer, CrossSuiTangCollect>> collectionMap = unionData.getCollectionMap();
            for (int cityId : needDealCity) {
                // 计算产量
                CrossSuiTangCollect productValue = getCityFoodProduct(unionRound.getWarType(), unionRound.getActGroupId(), cityId, nowTime, round);
                // 给所有玩家加
                addAllUserCityProductReward(unionId, cityId, productValue, collectionMap);
            }
            if (needDealCity.size() > 0) {
                unionData.setUpdateOption();
            }
        }
    }

    /**
     * 给同阵营所有玩家加采集奖励
     */
    private void addAllUserCityProductReward(String unionId, int cityId, CrossSuiTangCollect productValue, Map<Long, Map<Integer, CrossSuiTangCollect>> userCityValueMap) {
        if (unionId.isEmpty() || activity == null) {
            return;
        }
        Map<Long, CrossSuiTangUserData> userDataMap = activity.getUserDataMap();
        if (userDataMap == null) {
            return;
        }
        for (CrossSuiTangUserData userData : userDataMap.values()) {
            if (!activity.isAble(userData.getUserId()) || !Objects.equals(userData.getUnionUid(), unionId)) {
                continue;
            }

            if (!userCityValueMap.containsKey(userData.getUserId())) {
                userCityValueMap.put(userData.getUserId(), new ConcurrentHashMap<>());
            }
            Map<Integer, CrossSuiTangCollect> cityValueMap = userCityValueMap.get(userData.getUserId());

            CrossSuiTangCollect oldValue = cityValueMap.getOrDefault(cityId, new CrossSuiTangCollect());
            oldValue.setJunZi(oldValue.getJunZi() + productValue.getJunZi());
            oldValue.setMuBingLing(oldValue.getMuBingLing() + productValue.getMuBingLing());
            cityValueMap.put(cityId, oldValue);
        }
    }

    /*
     * 城池指定时间的采集产量
     */
    public CrossSuiTangCollect getCityFoodProduct(eSuiTangWarType warType, int actGroupId, int cityId, Long nowTime, int round) {
        CrossSuiTangCollect ret = new CrossSuiTangCollect();
        if (activity == null) {
            return ret;
        }
        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return ret;
        }
        Map<Integer, CrossSuiTangCity> cityMap = crossSuiTangData.getCityMap().get(round).get(warType).get(actGroupId);
        CrossSuiTangCity cityData = cityMap.get(cityId);
        // 收益多少次
        long times = (nowTime - cityData.getCollectionTime()) / DateHelper.MINUTE_MILLIONS;
        cityData.setCollectionTime(cityData.getCollectionTime() + times * DateHelper.MINUTE_MILLIONS);
        crossSuiTangData.setUpdateOption();

        BigInteger allValue = BigInteger.valueOf(times).multiply(BigInteger.valueOf(getCityFoodProductBuffPer(warType, actGroupId, cityId, round, eSuiTangBuffType.Type8_CityFoodProduce)));
        BigInteger muBingLingValue = BigInteger.valueOf(times).multiply(BigInteger.valueOf(getCityFoodProductBuffPer(warType, actGroupId, cityId, round, eSuiTangBuffType.Type2_CityMuBingLing)));
        ret.setJunZi(allValue.longValue());
        ret.setMuBingLing(muBingLingValue.longValue());
        return ret;
    }

    /**
     * buff后产量
     */
    public long getCityFoodProductBuffPer(eSuiTangWarType warType, int actGroupId, int cityId, int round, eSuiTangBuffType buffType) {
        if (activity == null) {
            return 0;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return 0;
        }

        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return 0;
        }

        Map<Integer, CrossSuiTangCity> cityMap = crossSuiTangData.getCityMap().get(round).get(warType).get(actGroupId);
        CrossSuiTangCity cityData = cityMap.get(cityId);
        SuiTangCityConfig cityConfig = config.getCityConfigMap().get(cityId);
        SuiTangCityTypeConfig cityTypeConfig = config.getCityTypeConfigMap().get(config.getCityTypeConfigKey(warType, cityConfig.getType()));
        Integer buffAddition = getBuffAddition(cityData.getUnionId(), buffType);
        if (buffType == eSuiTangBuffType.Type2_CityMuBingLing) {
            List<CrossSuiTangUnionBuff> buffs = getUnionBuff(cityData.getUnionId(), buffType);
            for (CrossSuiTangUnionBuff buff : buffs) {
                if (buff.getCityId() == cityId) {
                    return buffAddition.longValue();
                }
            }
            return 0;
        }
        BigDecimal production = BigDecimal.valueOf(cityTypeConfig.getFoodProduction())
                .multiply(BigDecimal.valueOf(1000 + buffAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN);
        return production.longValue();
    }

    /**
     * buff后产量(展示用)
     */
    public long getCityFoodProductBuffPer(eSuiTangWarType warType, int actGroupId, int cityId, int round, String unionId, eSuiTangBuffType buffType) {
        if (activity == null) {
            return 0;
        }
        SuiTangConfigSync config = activity.getConfig();
        if (config == null) {
            return 0;
        }

        CrossSuiTangData crossSuiTangData = activity.getCrossSuiTangData();
        if (crossSuiTangData == null) {
            return 0;
        }

        Map<Integer, CrossSuiTangCity> cityMap = crossSuiTangData.getCityMap().get(round).get(warType).get(actGroupId);
        CrossSuiTangCity cityData = cityMap.get(cityId);
        SuiTangCityConfig cityConfig = config.getCityConfigMap().get(cityId);
        SuiTangCityTypeConfig cityTypeConfig = config.getCityTypeConfigMap().get(config.getCityTypeConfigKey(warType, cityConfig.getType()));
        Integer buffAddition = cityData.getUnionId().equals(unionId) ? getBuffAddition(cityData.getUnionId(), buffType) : 0;
        if (buffType == eSuiTangBuffType.Type2_CityMuBingLing) {
            List<CrossSuiTangUnionBuff> buffs = getUnionBuff(cityData.getUnionId(), buffType);
            for (CrossSuiTangUnionBuff buff : buffs) {
                if (buff.getCityId() == cityId) {
                    return buffAddition.longValue();
                }
            }
            return 0;
        }
        BigDecimal production = BigDecimal.valueOf(cityTypeConfig.getFoodProduction())
                .multiply(BigDecimal.valueOf(1000 + buffAddition)).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_DOWN);
        return production.longValue();
    }

    /**
     * 邮件补发辎重
     */
    public void mailSendCityCollect() {

        synchronized (activity.getLock()) {

            for (CrossSuiTangUnionData unionData : activity.getUnionDataMap().values()) {
                makeAllCityCollect(unionData.getUnionUid(), activity.getConfig().getStage1TimeList().get(calcRound() - 1).get(1), calcRound());
            }

            // 统计全部玩家数据
            Map<Long, Map<Long, CrossSuiTangCollect>> serverUserCountMap = new ConcurrentHashMap<>();
            for (CrossSuiTangUserData userData : activity.getUserDataMap().values()) {
                long userId = userData.getUserId();
                // 没资格
                if (!activity.isAble(userData.getUserId())) {
                    continue;
                }
                CrossSuiTangUnionData unionData = getUnionData(userData.getUnionUid());
                if (unionData == null) {
                    continue;
                }
                long userAllValue = 0L;
                long muBingLing = 0L;
                for (CrossSuiTangCollect value : unionData.getCollectionMap().getOrDefault(userId, new ConcurrentHashMap<>()).values()) {
                    userAllValue += value.getJunZi();
                    muBingLing += value.getMuBingLing();
                }
                unionData.getCollectionMap().put(userId, new ConcurrentHashMap<>());
                if (userAllValue > 0 || muBingLing > 0) {
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                    if (userBaseInfo == null) {
                        logger.info("mailSendCityCollect can not find userInfo. activityId {} userId {} count {}.",
                                activity.getConfig().getActivityInfo().getActivityId(), userId, userAllValue);
                    } else {
                        serverUserCountMap.putIfAbsent(userBaseInfo.getServerId(), new ConcurrentHashMap<>());
                        CrossSuiTangCollect collect = new CrossSuiTangCollect();
                        collect.setMuBingLing(muBingLing);
                        collect.setJunZi(userAllValue);
                        serverUserCountMap.get(userBaseInfo.getServerId()).put(userId, collect);
                    }
                }
            }

            // 按区服发奖
            for (Map.Entry<Long, Map<Long, CrossSuiTangCollect>> entry : serverUserCountMap.entrySet()) {
                Long serverId = entry.getKey();
                SuiTang.CrossSuiTangMailSendCityCollectReqMsg.Builder builder = SuiTang.CrossSuiTangMailSendCityCollectReqMsg.newBuilder();
                for (Map.Entry<Long, CrossSuiTangCollect> longEntry : entry.getValue().entrySet()) {
                    long userId = longEntry.getKey();
                    long count = longEntry.getValue().getJunZi();
                    long muBingLing = longEntry.getValue().getMuBingLing();
                    SuiTang.CrossSuiTangCityCollectMsg.Builder tmp = SuiTang.CrossSuiTangCityCollectMsg.newBuilder();
                    tmp.setUserId(userId);
                    tmp.setCount(count);
                    tmp.setMuBingLing(muBingLing);
                    builder.addList(tmp);
                }
                YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_SUI_TANG_AUTO_SEND_CITY_COLLECT, builder);
                MessageHelper.sendPacket(serverId, 0, message);
            }
        }
    }
}
